package com.gframework.mybatis.dao.datasource;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;


/**
 * 多数据源切换注解.
 * <p>当你使用{@link RoutingDataSource}多数据源时，可以使用此注解用于spring bean方法上，来修改当前方法内执行的数据库操作会以特定的数据源进行处理。
 * 数据源则是通过{@link DynamicDataSourceManager}来进行获取。
 * <p>在使用此注解时，你必须了解以下情况：
 * <ul>
 * <li>修改数据源的AOP操作优先级最高(Integer.MIN_VALUE)，会首先执行也会最后退出。</li>
 * <li>此注解可用于方法、父方法、类、父类上，并且方法优先级高于类上的配置。</li>
 * <li>当已经处于事务中时，在调用含有此注解的方法，将无法修改数据源，因为事务会缓存数据库连接对象。<strong>但是此注解可以和事务注解同时使用，并且此注解会优先于事务注解执行。</strong></li>
 * <li>配置数据源id时，可以像使用{@code @Value}注解那样，使用"${}"来引用一个环境变量，或者使用"#{}"来执行一个SPEL表达式，甚至也可以混用。
 * 但是在使用"${}"时，请保证变量来源的安全性以避免XSS安全问题，因为"${}"内的参数会优先解析，而后再去判断SPEL并执行。这与{@code @Value}的解析逻辑是一致的。</li>
 * </ul>
 * @since 2.0.0
 * @author Ghwolf
 *
 * @see DynamicDataSourceManager DynamicDataSourceManager 多数据源管理器
 * @see RoutingDataSource RoutingDataSource 动态数据源
 */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface DataSource {
	
	/**
	 * 要修改的数据源id.
	 * <p>此id来自于{@link DynamicDataSourceManager}。
	 * <p>可以使用SPEL表达式，但是需要使用"#{}"包含，例如：#{'testDb'}
	 * <p>也可以使用"${}"来获取一个environment环境变量，例如：${datasource.dynamic.test.db.id}
	 */
	String value() ;

}
